package io.github.xxyopen.novel.service.impl;

import io.github.xxyopen.novel.dao.entity.Practice;
import io.github.xxyopen.novel.dao.mapper.PracticeMapper;
import io.github.xxyopen.novel.recommend.RecommendByStuBehaviorService;
import io.github.xxyopen.novel.recommend.RecommendByStuTeacherService;
import io.github.xxyopen.novel.service.RecommendService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import java.util.stream.Stream;

@Service
public class RecommendServiceImpl implements RecommendService {

    @Autowired
    private PracticeMapper practiceMapper;

    @Autowired
    private RecommendByStuBehaviorService recommendByStuBehaviorService;

    @Autowired
    private RecommendByStuTeacherService recommendByStuTeacherService;

    @Override
    public List<Practice> doubleRecommendation(Long stuId) {

        List<Practice> practiceSimply = practiceMapper.getPracticeSimply();

        // 用户为登录，则不使用推荐算法
        if(stuId==null){

            // 确保列表不为空且至少有5条数据
            if (practiceSimply != null && practiceSimply.size() >= 5) {
                // 打乱列表顺序
                Collections.shuffle(practiceSimply);

                // 取出前5条数据
                List<Practice> randomPractices = practiceSimply.subList(0, 5);

                // 打印输出随机选择的5条数据
                randomPractices.forEach(practice -> System.out.println(practice));
                return randomPractices;
            }

            return practiceSimply;
        }

        // 走推荐算法
        // 1根据学生实践关系推荐
        List<Practice> practicesFromStuBehavior = null;
        List<Long> recommendByStuBehavior = recommendByStuBehaviorService.recommend(Math.toIntExact(stuId));
        if (!recommendByStuBehavior.isEmpty()) {
            recommendByStuBehavior = recommendByStuBehavior.subList(0,Math.min(recommendByStuBehavior.size(), 5));
            practicesFromStuBehavior = practiceMapper.getPracticeByIds(recommendByStuBehavior);
        }
        // 2根据学生作者关系推荐
        List<Practice> practicesFromStuTeacher = null;
        List<Long> recommendByStuTeacher = recommendByStuTeacherService.recommend(Math.toIntExact(stuId));
        if (!recommendByStuTeacher.isEmpty()) {
            recommendByStuTeacher = recommendByStuTeacher.subList(0,Math.min(recommendByStuTeacher.size(), 5));
            practicesFromStuTeacher = practiceMapper.getPracticeByCreateByIds(recommendByStuTeacher);
        }

        // 获取最终选择的5条数据
        List<Practice> selectedPractices = selectPractices(practiceSimply, practicesFromStuBehavior, practicesFromStuTeacher, 5);

        return selectedPractices;
    }

    public static List<Practice> selectPractices(List<Practice> practiceSimply,
                                                 List<Practice> practicesFromStuBehavior,
                                                 List<Practice> practicesFromStuTeacher,
                                                 int limit) {

        // 合并三个列表，并确保id唯一，优先从practicesFromStuBehavior和practicesFromStuTeacher中取
        List<Practice> combined = Stream.concat(practicesFromStuBehavior.stream(), practicesFromStuTeacher.stream())
                .collect(Collectors.toList());

        // 如果不足5条，再从practiceSimply补充
        if (combined.size() < limit) {
            combined.addAll(practiceSimply);
        }

        // 使用流进行去重（根据id去重）
        Map<Long, Practice> uniquePractices = combined.stream()
                .collect(Collectors.toMap(Practice::getId, practice -> practice, (existing, replacement) -> existing));

        // 获取去重后的数据
        List<Practice> uniqueList = new ArrayList<>(uniquePractices.values());

        // 随机打乱列表
        Collections.shuffle(uniqueList);

        // 返回前 limit 条数据
        return uniqueList.stream()
                .limit(limit)  // 限制最终结果的数量为5条
                .collect(Collectors.toList());
    }
}
